As described in Subscribing to Data in Sparkplug Consumer, when you make a method call on the consumer object to subscribe to Sparkplug data, the data and status information come back in form of data notifications (events and/or callbacks).
This article describes the contents of the data notifications, their types, and how to process them.
Each data notification carries with it an event arguments objects. There is a separate type of the event arguments for metric notifications and payload notifications, but they both derive from the EasySparkplugNotificationEventArgs Class. This class contains members that are common to both metric and payload data notifications. The most important members are listed below.
The strings in the Sparkplug IDs (GroupId Property, EdgeNodeId Property, and DeviceId Property) have wildcards resolved, when possible. This means that if you have used a filter (such as "#") to specify the ID in the subscription, the value in the corresponding property will not contain the filter you specified, but rather the actual, concrete ID of the group, edge node or device to which the data notification carries the information. The Connect and Disconnect notification types, however, cannot be related to a specific Sparkplug component, and for them the properties contain the filter you have specified in the subscription.
The type of the data notification is contain in the NotificationType Property of the notitication event arguments, which can contain values from the SparkplugNotificationType Enumeration:
All subscriptions start in the disconnected state. It attempts to connect then (or it can reuse an existing connection). If the connection cannot be made, you will receive a Disconnect data notification, or even more of them if the problemn persists, over time. If/when the connection eventually succeeds, you will receive a Connect data notification. Only then the Birth, Data, and Death data notifications can follow. Eventually, the subscription is terminated with the Disconnect data notification.
Only the Birth and Data notifications contain the actual metric or payload. The remaining notifications are for status information.
In Sparkplug, the edge node or device announces its metrics and their metadata using the Birth message. The information contained in the Birth message is crucial for proper interpretation and processing of the Data messages that follow. It is, however, perfectly possible that a consumer (Sparkplug host applications) starts and/or wants to subscribe after the edge node or device has already sent the Birth message (this happens especially when the edge node is not configured with the primary host application ID). In such case, Rapid Toolkit for Sparkplug automatically issues a "request rebirth" command to the edge node or device, so that it resends the Birth message and the consumer can process it.
In other cases, your code can be making a subscription, and Rapid Toolkit for Sparkplug already has enough information about the metrics and metadata - possibly because it has received the Birth message before. In such case, Rapid Toolkit for Sparkplug will simply reuse the information it already has, and synthesize the Birth message as if it was just produced. This way, your code can expect that the order of the incoming notifications will be Birth - Data - Data - Data - .... - Death (keeping in mind that Disconnect and Connect notifications can interrupt the sequence).
Whether or not the particular notification has been synthesized is indicated by the IsSynthesized Property available in the event arguments of the notification.
When you make a subscription using any of the methods described under Subscribing to Metrics in Subscribing to Data in Sparkplug Consumer, the data notifications will be delivered to you using the MetricNotification Event on the consumer object (and, optionally, using a callback - see further down in this article). The metric data notification carries with it an instance of the EasySparkplugMetricNotificationEventArgs Class. In addition to the members common to all data notifications (described earlier in this article), this object provides
The metric name has wildcards resolved, when possible, i.e. if you have used a filter (such as "#") to specify the metric name in the subscription, the MetricName Property does not contain the filter you specified, but rather the actual, concrete name of the metric to which the data notification carries the information. The Connect and Disconnect notification types, however, cannot be related to a specific Sparkplug component, and for them the property contains the filter you have specified in the subscription.
In Sparkplug, metadata is normally provided in the Birth messages only. Rapid Toolkit for Sparkplug, however, replicates the metadata from the Birth message into the subsequent Data notifications for the same metric, so that your code does not have to store the Birth notifications and correlate them with the Data notifications.
The following example illustrates processing of a metric notification.
When you make a subscription using any of the methods described under Subscribing to Payloads in Subscribing to Data in Sparkplug Consumer, the data notifications will be delivered to you using the PayloadNotification Event on the consumer object (and, optionally, using a callback - see further down in this article). The payload data notification carries with it an instance of the EasySparkplugPayloadNotificationEventArgs Class. In addition to the members common to all data notifications (described earlier in this article), this object provides
The payload is an instance of the SparkplugPayload Class, and it acts as a collection of payload elements. Each payload element is key-value pair, where the key is the name of the metric, and the value is an instance of the SparkplugMetricElement Class, containing the metric data, and optionally a metadata for the same metric. Alternatively, the information in the payload can be accessed through dictionaries, keyed by the metric name. For metrics contained in the payload, the MetricDataDictionary Property contains a read-only dictionary of Sparkplug metric data, and the MetadataDictionary Property contains a read-only dictionary of Sparkplug metadata for the same metrics (or their subset, as the metadata is optional).
Note that in Sparkplug, metadata is normally provided in the Birth messages only. Rapid Toolkit for Sparkplug, however, replicates the metadata from the Birth message into the subsequent Data notifications for the same metric, so that your code does not have to store the Birth notifications and correlate them with the Data notifications.
The following example illustrates processing of a payload notification.
Data notifications originating in the consumer object are always delivered as events. In addition, when making the subscription, you can also specify a callback. The callback is a method that will be called (in addition to raising the event) for each data notification for the subscription you are making. There are some differences between the events and callbacks (such as that the events are common for all subscritpions on the consumer object), but in general, both approaches can do the job. Whether you use the events, or callbacks, is largely a decision that depends on the code clarity in your particular case, and perhaps even your personal coding preferences.
Generally, the callback is specified using a property in the argument object passed to the subscription method. It is the EasySparkplugMetricSubscriptionArguments.Callback Property when subscribing to metrics, or the EasySparkplugPayloadSubscriptionArguments.Callback Property when subscribing to payloads. By default, this property is null, and no callback takes place (onlyan event is raised). When this property is set to a non-null method reference, the method is called for data notifications from the subscription, in addition to raising the event.
Usually, you do not assemble the argument object passed to the subscription method in your code. There are various overloads and extension method for making the subscriptions, and may of them include the callback as a separate argument. This way, you can simply specify the callback method as one of the arguments to the subscription method call. The necessary argument object, and filling in of the Callback property, happens behind the scenes for you.
The following example illustrates how a lambda method can be used as a callback for data notifications from edge node metrics.
If you make multiple subscriptions on the same consumer object, you may have a need to distinguish in the incoming notifications where they came from (which subscription has caused them). There are several ways to achieve it:
The following example illustrates how to subscribe to Sparkplug metrics, and identify the subscriptions using an integer value.
Sparkplug is a trademark of Eclipse Foundation, Inc. "MQTT" is a trademark of the OASIS Open standards consortium. Other related terms are trademarks of their respective owners. Any use of these terms on this site is for descriptive purposes only and does not imply any sponsorship, endorsement or affiliation.